{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "_You are currently looking at **version 1.1** of this notebook. To download notebooks and datafiles, as well as get help on Jupyter notebooks in the Coursera platform, visit the [Jupyter Notebook FAQ](https://www.coursera.org/learn/python-data-analysis/resources/0dhYG) course resource._\n",
    "\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# The Python Programming Language: Functions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "`add_numbers` is a function that takes two numbers and adds them together."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def add_numbers(x, y):\n",
    "    return x + y\n",
    "\n",
    "add_numbers(1, 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "`add_numbers` updated to take an optional 3rd parameter. Using `print` allows printing of multiple expressions within a single cell."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def add_numbers(x,y,z=None):\n",
    "    if (z==None):\n",
    "        return x+y\n",
    "    else:\n",
    "        return x+y+z\n",
    "\n",
    "print(add_numbers(1, 2))\n",
    "print(add_numbers(1, 2, 3))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "`add_numbers` updated to take an optional flag parameter."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def add_numbers(x, y, z=None, flag=False):\n",
    "    if (flag):\n",
    "        print('Flag is true!')\n",
    "    if (z==None):\n",
    "        return x + y\n",
    "    else:\n",
    "        return x + y + z\n",
    "    \n",
    "print(add_numbers(1, 2, flag=True))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Assign function `add_numbers` to variable `a`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def add_numbers(x,y):\n",
    "    return x+y\n",
    "\n",
    "a = add_numbers\n",
    "a(1,2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "# The Python Programming Language: Types and Sequences"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Use `type` to return the object's type."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "type('This is a string')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "type(None)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "type(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "type(1.0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "type(add_numbers)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Tuples are an immutable data structure (cannot be altered)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "x = (1, 'a', 2, 'b')\n",
    "type(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Lists are a mutable data structure."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "x = [1, 'a', 2, 'b']\n",
    "type(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Use `append` to append an object to a list."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n"
     ]
    }
   ],
   "source": [
    "x=[]\n",
    "# x.append(3.3)\n",
    "for i in range(10):\n",
    "    x.append(i)\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "This is an example of how to loop through each item in the list."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "for item in x:\n",
    "    print(item)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Or using the indexing operator:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "i=0\n",
    "while( i != len(x) ):\n",
    "    print(x[i])\n",
    "    i = i + 1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Use `+` to concatenate lists."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "[1,2] + [3,4]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Use `*` to repeat lists."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "[1]*3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Use the `in` operator to check if something is inside a list."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "1 in [1, 2, 3]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Now let's look at strings. Use bracket notation to slice a string."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "x = 'This is a string'\n",
    "print(x[0]) #first character\n",
    "print(x[0:1]) #first character, but we have explicitly set the end character\n",
    "print(x[0:2]) #first two characters\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "This will return the last element of the string."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "x[-1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "This will return the slice starting from the 4th element from the end and stopping before the 2nd element from the end."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "x[-4:-2]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "This is a slice from the beginning of the string and stopping before the 3rd element."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "x[:3]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "And this is a slice starting from the 4th element of the string and going all the way to the end."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "x[3:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "firstname = 'Christopher'\n",
    "lastname = 'Brooks'\n",
    "\n",
    "print(firstname + ' ' + lastname)\n",
    "print(firstname*3)\n",
    "print('Chris' in firstname)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "`split` returns a list of all the words in a string, or a list split on a specific character."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "firstname = 'Christopher Arthur Hansen Brooks'.split(' ')[0] # [0] selects the first element of the list\n",
    "lastname = 'Christopher Arthur Hansen Brooks'.split(' ')[-1] # [-1] selects the last element of the list\n",
    "print(firstname)\n",
    "print(lastname)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Make sure you convert objects to strings before concatenating."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "'Chris' + 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "'Chris' + str(2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Dictionaries associate keys with values."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "x = {'Christopher Brooks': 'brooksch@umich.edu', 'Bill Gates': 'billg@microsoft.com'}\n",
    "x['Christopher Brooks'] # Retrieve a value by using the indexing operator\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "x['Kevyn Collins-Thompson'] = None\n",
    "x['Kevyn Collins-Thompson']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Iterate over all of the keys:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true,
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "for name in x:\n",
    "    print(x[name])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Iterate over all of the values:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "for email in x.values():\n",
    "    print(email)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Iterate over all of the items in the list:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "for name, email in x.items():\n",
    "    print(name)\n",
    "    print(email)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "You can unpack a sequence into different variables:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "x = ('Christopher', 'Brooks', 'brooksch@umich.edu')\n",
    "fname, lname, email = x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "fname"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "lname"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Make sure the number of values you are unpacking matches the number of variables being assigned."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "x = ('Christopher', 'Brooks', 'brooksch@umich.edu', 'Ann Arbor')\n",
    "fname, lname, email = x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "# The Python Programming Language: More on Strings"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "print('Chris' + 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "print('Chris' + str(2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Python has a built in method for convenient string formatting."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Chris bought 4 item(s) at a price of 3.24 each for a total of 12.96\n"
     ]
    }
   ],
   "source": [
    "sales_record = {\n",
    "'price': 3.24,\n",
    "'num_items': 4,\n",
    "'person': 'Chris'}\n",
    "\n",
    "sales_statement = '{} bought {} item(s) at a price of {} each for a total of {}'\n",
    "\n",
    "print(sales_statement.format(sales_record['person'],\n",
    "                             sales_record['num_items'],\n",
    "                             sales_record['price'],\n",
    "                             sales_record['num_items']*sales_record['price']))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "# Reading and Writing CSV files"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Let's import our datafile mpg.csv, which contains fuel economy data for 234 cars.\n",
    "\n",
    "* mpg : miles per gallon\n",
    "* class : car classification\n",
    "* cty : city mpg\n",
    "* cyl : # of cylinders\n",
    "* displ : engine displacement in liters\n",
    "* drv : f = front-wheel drive, r = rear wheel drive, 4 = 4wd\n",
    "* fl : fuel (e = ethanol E85, d = diesel, r = regular, p = premium, c = CNG)\n",
    "* hwy : highway mpg\n",
    "* manufacturer : automobile manufacturer\n",
    "* model : model of car\n",
    "* trans : type of transmission\n",
    "* year : model year"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true,
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "import csv\n",
    "\n",
    "%precision 2\n",
    "\n",
    "with open('mpg.csv') as csvfile:\n",
    "    mpg = list(csv.DictReader(csvfile))\n",
    "    \n",
    "mpg[:3] # The first three dictionaries in our list."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "`csv.Dictreader` has read in each row of our csv file as a dictionary. `len` shows that our list is comprised of 234 dictionaries."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "len(mpg)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "`keys` gives us the column names of our csv."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "mpg[0].keys()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "This is how to find the average cty fuel economy across all cars. All values in the dictionaries are strings, so we need to convert to float."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "sum(float(d['cty']) for d in mpg) / len(mpg)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Similarly this is how to find the average hwy fuel economy across all cars."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "sum(float(d['hwy']) for d in mpg) / len(mpg)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Use `set` to return the unique values for the number of cylinders the cars in our dataset have."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "cylinders = set(d['cyl'] for d in mpg)\n",
    "cylinders"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Here's a more complex example where we are grouping the cars by number of cylinder, and finding the average cty mpg for each group."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "CtyMpgByCyl = []\n",
    "\n",
    "for c in cylinders: # iterate over all the cylinder levels\n",
    "    summpg = 0\n",
    "    cyltypecount = 0\n",
    "    for d in mpg: # iterate over all dictionaries\n",
    "        if d['cyl'] == c: # if the cylinder level type matches,\n",
    "            summpg += float(d['cty']) # add the cty mpg\n",
    "            cyltypecount += 1 # increment the count\n",
    "    CtyMpgByCyl.append((c, summpg / cyltypecount)) # append the tuple ('cylinder', 'avg mpg')\n",
    "\n",
    "CtyMpgByCyl.sort(key=lambda x: x[0])\n",
    "CtyMpgByCyl"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Use `set` to return the unique values for the class types in our dataset."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "vehicleclass = set(d['class'] for d in mpg) # what are the class types\n",
    "vehicleclass"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "And here's an example of how to find the average hwy mpg for each class of vehicle in our dataset."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "HwyMpgByClass = []\n",
    "\n",
    "for t in vehicleclass: # iterate over all the vehicle classes\n",
    "    summpg = 0\n",
    "    vclasscount = 0\n",
    "    for d in mpg: # iterate over all dictionaries\n",
    "        if d['class'] == t: # if the cylinder amount type matches,\n",
    "            summpg += float(d['hwy']) # add the hwy mpg\n",
    "            vclasscount += 1 # increment the count\n",
    "    HwyMpgByClass.append((t, summpg / vclasscount)) # append the tuple ('class', 'avg mpg')\n",
    "\n",
    "HwyMpgByClass.sort(key=lambda x: x[1])\n",
    "HwyMpgByClass"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "# The Python Programming Language: Dates and Times"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import datetime as dt\n",
    "import time as tm"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "`time` returns the current time in seconds since the Epoch. (January 1st, 1970)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "tm.time()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Convert the timestamp to datetime."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "dtnow = dt.datetime.fromtimestamp(tm.time())\n",
    "dtnow"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Handy datetime attributes:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "dtnow.year, dtnow.month, dtnow.day, dtnow.hour, dtnow.minute, dtnow.second # get year, month, day, etc.from a datetime"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "`timedelta` is a duration expressing the difference between two dates."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "delta = dt.timedelta(days = 100) # create a timedelta of 100 days\n",
    "delta"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "`date.today` returns the current local date."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "today = dt.date.today()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "today - delta # the date 100 days ago"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "today > today-delta # compare dates"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "# The Python Programming Language: Objects and map()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "An example of a class in python:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "class Person:\n",
    "    department = 'School of Information' #a class variable\n",
    "\n",
    "    def set_name(self, new_name): #a method\n",
    "        self.name = new_name\n",
    "    def set_location(self, new_location):\n",
    "        self.location = new_location"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "person = Person()\n",
    "person.set_name('Christopher Brooks')\n",
    "person.set_location('Ann Arbor, MI, USA')\n",
    "print('{} live in {} and works in the department {}'.format(person.name, person.location, person.department))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Here's an example of mapping the `min` function between two lists."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "store1 = [10.00, 11.00, 12.34, 2.34]\n",
    "store2 = [9.00, 11.10, 12.34, 2.01]\n",
    "cheapest = map(min, store1, store2)\n",
    "cheapest"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Now let's iterate through the map object to see the values."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true,
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "for item in cheapest:\n",
    "    print(item)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "# The Python Programming Language: Lambda and List Comprehensions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Here's an example of lambda that takes in three parameters and adds the first two."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "my_function = lambda a, b, c : a + b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "my_function(1, 2, 3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Let's iterate from 0 to 999 and return the even numbers."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "my_list = []\n",
    "for number in range(0, 1000):\n",
    "    if number % 2 == 0:\n",
    "        my_list.append(number)\n",
    "my_list"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Now the same thing but with list comprehension."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0,\n",
       " 2,\n",
       " 4,\n",
       " 6,\n",
       " 8,\n",
       " 10,\n",
       " 12,\n",
       " 14,\n",
       " 16,\n",
       " 18,\n",
       " 20,\n",
       " 22,\n",
       " 24,\n",
       " 26,\n",
       " 28,\n",
       " 30,\n",
       " 32,\n",
       " 34,\n",
       " 36,\n",
       " 38,\n",
       " 40,\n",
       " 42,\n",
       " 44,\n",
       " 46,\n",
       " 48,\n",
       " 50,\n",
       " 52,\n",
       " 54,\n",
       " 56,\n",
       " 58,\n",
       " 60,\n",
       " 62,\n",
       " 64,\n",
       " 66,\n",
       " 68,\n",
       " 70,\n",
       " 72,\n",
       " 74,\n",
       " 76,\n",
       " 78,\n",
       " 80,\n",
       " 82,\n",
       " 84,\n",
       " 86,\n",
       " 88,\n",
       " 90,\n",
       " 92,\n",
       " 94,\n",
       " 96,\n",
       " 98,\n",
       " 100,\n",
       " 102,\n",
       " 104,\n",
       " 106,\n",
       " 108,\n",
       " 110,\n",
       " 112,\n",
       " 114,\n",
       " 116,\n",
       " 118,\n",
       " 120,\n",
       " 122,\n",
       " 124,\n",
       " 126,\n",
       " 128,\n",
       " 130,\n",
       " 132,\n",
       " 134,\n",
       " 136,\n",
       " 138,\n",
       " 140,\n",
       " 142,\n",
       " 144,\n",
       " 146,\n",
       " 148,\n",
       " 150,\n",
       " 152,\n",
       " 154,\n",
       " 156,\n",
       " 158,\n",
       " 160,\n",
       " 162,\n",
       " 164,\n",
       " 166,\n",
       " 168,\n",
       " 170,\n",
       " 172,\n",
       " 174,\n",
       " 176,\n",
       " 178,\n",
       " 180,\n",
       " 182,\n",
       " 184,\n",
       " 186,\n",
       " 188,\n",
       " 190,\n",
       " 192,\n",
       " 194,\n",
       " 196,\n",
       " 198,\n",
       " 200,\n",
       " 202,\n",
       " 204,\n",
       " 206,\n",
       " 208,\n",
       " 210,\n",
       " 212,\n",
       " 214,\n",
       " 216,\n",
       " 218,\n",
       " 220,\n",
       " 222,\n",
       " 224,\n",
       " 226,\n",
       " 228,\n",
       " 230,\n",
       " 232,\n",
       " 234,\n",
       " 236,\n",
       " 238,\n",
       " 240,\n",
       " 242,\n",
       " 244,\n",
       " 246,\n",
       " 248,\n",
       " 250,\n",
       " 252,\n",
       " 254,\n",
       " 256,\n",
       " 258,\n",
       " 260,\n",
       " 262,\n",
       " 264,\n",
       " 266,\n",
       " 268,\n",
       " 270,\n",
       " 272,\n",
       " 274,\n",
       " 276,\n",
       " 278,\n",
       " 280,\n",
       " 282,\n",
       " 284,\n",
       " 286,\n",
       " 288,\n",
       " 290,\n",
       " 292,\n",
       " 294,\n",
       " 296,\n",
       " 298,\n",
       " 300,\n",
       " 302,\n",
       " 304,\n",
       " 306,\n",
       " 308,\n",
       " 310,\n",
       " 312,\n",
       " 314,\n",
       " 316,\n",
       " 318,\n",
       " 320,\n",
       " 322,\n",
       " 324,\n",
       " 326,\n",
       " 328,\n",
       " 330,\n",
       " 332,\n",
       " 334,\n",
       " 336,\n",
       " 338,\n",
       " 340,\n",
       " 342,\n",
       " 344,\n",
       " 346,\n",
       " 348,\n",
       " 350,\n",
       " 352,\n",
       " 354,\n",
       " 356,\n",
       " 358,\n",
       " 360,\n",
       " 362,\n",
       " 364,\n",
       " 366,\n",
       " 368,\n",
       " 370,\n",
       " 372,\n",
       " 374,\n",
       " 376,\n",
       " 378,\n",
       " 380,\n",
       " 382,\n",
       " 384,\n",
       " 386,\n",
       " 388,\n",
       " 390,\n",
       " 392,\n",
       " 394,\n",
       " 396,\n",
       " 398,\n",
       " 400,\n",
       " 402,\n",
       " 404,\n",
       " 406,\n",
       " 408,\n",
       " 410,\n",
       " 412,\n",
       " 414,\n",
       " 416,\n",
       " 418,\n",
       " 420,\n",
       " 422,\n",
       " 424,\n",
       " 426,\n",
       " 428,\n",
       " 430,\n",
       " 432,\n",
       " 434,\n",
       " 436,\n",
       " 438,\n",
       " 440,\n",
       " 442,\n",
       " 444,\n",
       " 446,\n",
       " 448,\n",
       " 450,\n",
       " 452,\n",
       " 454,\n",
       " 456,\n",
       " 458,\n",
       " 460,\n",
       " 462,\n",
       " 464,\n",
       " 466,\n",
       " 468,\n",
       " 470,\n",
       " 472,\n",
       " 474,\n",
       " 476,\n",
       " 478,\n",
       " 480,\n",
       " 482,\n",
       " 484,\n",
       " 486,\n",
       " 488,\n",
       " 490,\n",
       " 492,\n",
       " 494,\n",
       " 496,\n",
       " 498,\n",
       " 500,\n",
       " 502,\n",
       " 504,\n",
       " 506,\n",
       " 508,\n",
       " 510,\n",
       " 512,\n",
       " 514,\n",
       " 516,\n",
       " 518,\n",
       " 520,\n",
       " 522,\n",
       " 524,\n",
       " 526,\n",
       " 528,\n",
       " 530,\n",
       " 532,\n",
       " 534,\n",
       " 536,\n",
       " 538,\n",
       " 540,\n",
       " 542,\n",
       " 544,\n",
       " 546,\n",
       " 548,\n",
       " 550,\n",
       " 552,\n",
       " 554,\n",
       " 556,\n",
       " 558,\n",
       " 560,\n",
       " 562,\n",
       " 564,\n",
       " 566,\n",
       " 568,\n",
       " 570,\n",
       " 572,\n",
       " 574,\n",
       " 576,\n",
       " 578,\n",
       " 580,\n",
       " 582,\n",
       " 584,\n",
       " 586,\n",
       " 588,\n",
       " 590,\n",
       " 592,\n",
       " 594,\n",
       " 596,\n",
       " 598,\n",
       " 600,\n",
       " 602,\n",
       " 604,\n",
       " 606,\n",
       " 608,\n",
       " 610,\n",
       " 612,\n",
       " 614,\n",
       " 616,\n",
       " 618,\n",
       " 620,\n",
       " 622,\n",
       " 624,\n",
       " 626,\n",
       " 628,\n",
       " 630,\n",
       " 632,\n",
       " 634,\n",
       " 636,\n",
       " 638,\n",
       " 640,\n",
       " 642,\n",
       " 644,\n",
       " 646,\n",
       " 648,\n",
       " 650,\n",
       " 652,\n",
       " 654,\n",
       " 656,\n",
       " 658,\n",
       " 660,\n",
       " 662,\n",
       " 664,\n",
       " 666,\n",
       " 668,\n",
       " 670,\n",
       " 672,\n",
       " 674,\n",
       " 676,\n",
       " 678,\n",
       " 680,\n",
       " 682,\n",
       " 684,\n",
       " 686,\n",
       " 688,\n",
       " 690,\n",
       " 692,\n",
       " 694,\n",
       " 696,\n",
       " 698,\n",
       " 700,\n",
       " 702,\n",
       " 704,\n",
       " 706,\n",
       " 708,\n",
       " 710,\n",
       " 712,\n",
       " 714,\n",
       " 716,\n",
       " 718,\n",
       " 720,\n",
       " 722,\n",
       " 724,\n",
       " 726,\n",
       " 728,\n",
       " 730,\n",
       " 732,\n",
       " 734,\n",
       " 736,\n",
       " 738,\n",
       " 740,\n",
       " 742,\n",
       " 744,\n",
       " 746,\n",
       " 748,\n",
       " 750,\n",
       " 752,\n",
       " 754,\n",
       " 756,\n",
       " 758,\n",
       " 760,\n",
       " 762,\n",
       " 764,\n",
       " 766,\n",
       " 768,\n",
       " 770,\n",
       " 772,\n",
       " 774,\n",
       " 776,\n",
       " 778,\n",
       " 780,\n",
       " 782,\n",
       " 784,\n",
       " 786,\n",
       " 788,\n",
       " 790,\n",
       " 792,\n",
       " 794,\n",
       " 796,\n",
       " 798,\n",
       " 800,\n",
       " 802,\n",
       " 804,\n",
       " 806,\n",
       " 808,\n",
       " 810,\n",
       " 812,\n",
       " 814,\n",
       " 816,\n",
       " 818,\n",
       " 820,\n",
       " 822,\n",
       " 824,\n",
       " 826,\n",
       " 828,\n",
       " 830,\n",
       " 832,\n",
       " 834,\n",
       " 836,\n",
       " 838,\n",
       " 840,\n",
       " 842,\n",
       " 844,\n",
       " 846,\n",
       " 848,\n",
       " 850,\n",
       " 852,\n",
       " 854,\n",
       " 856,\n",
       " 858,\n",
       " 860,\n",
       " 862,\n",
       " 864,\n",
       " 866,\n",
       " 868,\n",
       " 870,\n",
       " 872,\n",
       " 874,\n",
       " 876,\n",
       " 878,\n",
       " 880,\n",
       " 882,\n",
       " 884,\n",
       " 886,\n",
       " 888,\n",
       " 890,\n",
       " 892,\n",
       " 894,\n",
       " 896,\n",
       " 898,\n",
       " 900,\n",
       " 902,\n",
       " 904,\n",
       " 906,\n",
       " 908,\n",
       " 910,\n",
       " 912,\n",
       " 914,\n",
       " 916,\n",
       " 918,\n",
       " 920,\n",
       " 922,\n",
       " 924,\n",
       " 926,\n",
       " 928,\n",
       " 930,\n",
       " 932,\n",
       " 934,\n",
       " 936,\n",
       " 938,\n",
       " 940,\n",
       " 942,\n",
       " 944,\n",
       " 946,\n",
       " 948,\n",
       " 950,\n",
       " 952,\n",
       " 954,\n",
       " 956,\n",
       " 958,\n",
       " 960,\n",
       " 962,\n",
       " 964,\n",
       " 966,\n",
       " 968,\n",
       " 970,\n",
       " 972,\n",
       " 974,\n",
       " 976,\n",
       " 978,\n",
       " 980,\n",
       " 982,\n",
       " 984,\n",
       " 986,\n",
       " 988,\n",
       " 990,\n",
       " 992,\n",
       " 994,\n",
       " 996,\n",
       " 998]"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "my_list = [number for number in range(0,1000) if number % 2 == 0]\n",
    "my_list"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "<br>\n",
    "# The Python Programming Language: Numerical Python (NumPy)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "## Creating Arrays"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Create a list and convert it to a numpy array"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "mylist = [1, 2, 3]\n",
    "x = np.array(mylist)\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Or just pass in a list directly"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "y = np.array([4, 5, 6])\n",
    "y"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Pass in a list of lists to create a multidimensional array."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "m = np.array([[7, 8, 9], [10, 11, 12]])\n",
    "m"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Use the shape method to find the dimensions of the array. (rows, columns)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "m.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "`arange` returns evenly spaced values within a given interval."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "n = np.arange(0, 30, 2) # start at 0 count up by 2, stop before 30\n",
    "n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "`reshape` returns an array with the same data with a new shape."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "n = n.reshape(3, 5) # reshape array to be 3x5\n",
    "n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "`linspace` returns evenly spaced numbers over a specified interval."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "o = np.linspace(0, 4, 9) # return 9 evenly spaced values from 0 to 4\n",
    "o"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "`resize` changes the shape and size of array in-place."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "o.resize(3, 3)\n",
    "o"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "`ones` returns a new array of given shape and type, filled with ones."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "np.ones((3, 2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "`zeros` returns a new array of given shape and type, filled with zeros."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "np.zeros((2, 3))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "`eye` returns a 2-D array with ones on the diagonal and zeros elsewhere."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "np.eye(3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "`diag` extracts a diagonal or constructs a diagonal array."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "np.diag(y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Create an array using repeating list (or see `np.tile`)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "np.array([1, 2, 3] * 3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Repeat elements of an array using `repeat`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "np.repeat([1, 2, 3], 3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "#### Combining Arrays"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "p = np.ones([2, 3], int)\n",
    "p"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Use `vstack` to stack arrays in sequence vertically (row wise)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "np.vstack([p, 2*p])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Use `hstack` to stack arrays in sequence horizontally (column wise)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "np.hstack([p, 2*p])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "## Operations"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Use `+`, `-`, `*`, `/` and `**` to perform element wise addition, subtraction, multiplication, division and power."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "print(x + y) # elementwise addition     [1 2 3] + [4 5 6] = [5  7  9]\n",
    "print(x - y) # elementwise subtraction  [1 2 3] - [4 5 6] = [-3 -3 -3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "print(x * y) # elementwise multiplication  [1 2 3] * [4 5 6] = [4  10  18]\n",
    "print(x / y) # elementwise divison         [1 2 3] / [4 5 6] = [0.25  0.4  0.5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "print(x**2) # elementwise power  [1 2 3] ^2 =  [1 4 9]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "**Dot Product:**  \n",
    "\n",
    "$ \\begin{bmatrix}x_1 \\ x_2 \\ x_3\\end{bmatrix}\n",
    "\\cdot\n",
    "\\begin{bmatrix}y_1 \\\\ y_2 \\\\ y_3\\end{bmatrix}\n",
    "= x_1 y_1 + x_2 y_2 + x_3 y_3$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "x.dot(y) # dot product  1*4 + 2*5 + 3*6"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "z = np.array([y, y**2])\n",
    "print(len(z)) # number of rows of array"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Let's look at transposing arrays. Transposing permutes the dimensions of the array."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "z = np.array([y, y**2])\n",
    "z"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "The shape of array `z` is `(2,3)` before transposing."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "z.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Use `.T` to get the transpose."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "z.T"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "The number of rows has swapped with the number of columns."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "z.T.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Use `.dtype` to see the data type of the elements in the array."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "z.dtype"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Use `.astype` to cast to a specific type."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "z = z.astype('f')\n",
    "z.dtype"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "## Math Functions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Numpy has many built in math functions that can be performed on arrays."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "a = np.array([-4, -2, 1, 3, 5])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "a.sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "a.max()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "a.min()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "a.mean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "a.std()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "`argmax` and `argmin` return the index of the maximum and minimum values in the array."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "a.argmax()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "a.argmin()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "## Indexing / Slicing"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "s = np.arange(13)**2\n",
    "s"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Use bracket notation to get the value at a specific index. Remember that indexing starts at 0."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "s[0], s[4], s[-1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Use `:` to indicate a range. `array[start:stop]`\n",
    "\n",
    "\n",
    "Leaving `start` or `stop` empty will default to the beginning/end of the array."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "s[1:5]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Use negatives to count from the back."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "s[-4:]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "A second `:` can be used to indicate step-size. `array[start:stop:stepsize]`\n",
    "\n",
    "Here we are starting 5th element from the end, and counting backwards by 2 until the beginning of the array is reached."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "s[-5::-2]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Let's look at a multidimensional array."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "r = np.arange(36)\n",
    "r.resize((6, 6))\n",
    "r"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Use bracket notation to slice: `array[row, column]`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "r[2, 2]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "And use : to select a range of rows or columns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "r[3, 3:6]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Here we are selecting all the rows up to (and not including) row 2, and all the columns up to (and not including) the last column."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "r[:2, :-1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "This is a slice of the last row, and only every other element."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "r[-1, ::2]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "We can also perform conditional indexing. Here we are selecting values from the array that are greater than 30. (Also see `np.where`)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "r[r > 30]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Here we are assigning all values in the array that are greater than 30 to the value of 30."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "r[r > 30] = 30\n",
    "r"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "## Copying Data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Be careful with copying and modifying arrays in NumPy!\n",
    "\n",
    "\n",
    "`r2` is a slice of `r`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "r2 = r[:3,:3]\n",
    "r2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Set this slice's values to zero ([:] selects the entire array)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "r2[:] = 0\n",
    "r2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "`r` has also been changed!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "r"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "To avoid this, use `r.copy` to create a copy that will not affect the original array"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "r_copy = r.copy()\n",
    "r_copy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Now when r_copy is modified, r will not be changed."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "r_copy[:] = 10\n",
    "print(r_copy, '\\n')\n",
    "print(r)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "### Iterating Over Arrays"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's create a new 4 by 3 array of random numbers 0-9."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "test = np.random.randint(0, 10, (4,3))\n",
    "test"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Iterate by row:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "for row in test:\n",
    "    print(row)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Iterate by index:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "for i in range(len(test)):\n",
    "    print(test[i])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Iterate by row and index:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "for i, row in enumerate(test):\n",
    "    print('row', i, 'is', row)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "Use `zip` to iterate over multiple iterables."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "test2 = test**2\n",
    "test2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "for i, j in zip(test, test2):\n",
    "    print(i,'+',j,'=',i+j)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (UM)",
   "language": "python",
   "name": "logging"
  },
  "language_info": {
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
